﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using JsonToCSharp;

namespace ExcelConverter
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        private const int SAVE_CONTENT_COUNT = 3;
        private const string CONFIG_PATH = "./j2c_config.ini";
        
        private static Encoding s_encoding = new UTF8Encoding(false);
        private readonly List<string> _cachedPathList = new List<string>();
        public MainWindow()
        {
            InitializeComponent();

            if (File.Exists(CONFIG_PATH))
            {
                var pathPairs = File.ReadAllLines(CONFIG_PATH, s_encoding);
                for (var i = 0; i < pathPairs.Length; i++)
                {
                    var pairStr = pathPairs[i];
                    var pathPair = pairStr.Split('|');
                    if (pathPair.Length == SAVE_CONTENT_COUNT)
                    {
                        if (!_cachedPathList.Contains(pairStr))
                        {
                            _cachedPathList.Add(pairStr);
                        }
                    }
                }
                RefreshCachedPathMenu();
            }
            ApplyPath(0);
        }
        private void RefreshCachedPathMenu()
        {
            SavedPath.Items.Clear();
            for (var i = 0; i < _cachedPathList.Count; i++)
            {
                var index = i;
                var path = _cachedPathList[i];
                //选项
                var pathMenuItem = new MenuItem();
                pathMenuItem.Header = path.Replace("|", "\n") + " (右键选择)";
                pathMenuItem.FontSize = 22;
                pathMenuItem.Background = new SolidColorBrush(Colors.LightGray);
                pathMenuItem.MouseUp += (sender, args) =>
                {
                    if (ApplyPath(index))
                    {
                        //失焦
                        SavedPath.IsSubmenuOpen = false;
                        //把应用的放在第一位
                        if (index != 0)
                        {
                            (_cachedPathList[index], _cachedPathList[0]) = (_cachedPathList[0], _cachedPathList[index]);
                            RefreshCachedPathMenu();
                        }
                    }
                };
                //移除
                {
                    var deleteMenuItem = new MenuItem();
                    deleteMenuItem.Header = "移除";
                    deleteMenuItem.FontSize = 22;
                    deleteMenuItem.Background = new SolidColorBrush(Colors.Salmon);
                    deleteMenuItem.Click += (sender, args) =>
                    {
                        _cachedPathList.RemoveAt(index);
                        RefreshCachedPathMenu();
                    };
                    pathMenuItem.Items.Add(deleteMenuItem);
                }
                SavedPath.Items.Add(pathMenuItem);
            }
            //清空
            {
                var clearMenuItem = new MenuItem();
                clearMenuItem.Header = "清空";
                clearMenuItem.FontSize = 22;
                clearMenuItem.Background = new SolidColorBrush(Colors.Salmon);
                clearMenuItem.Click += (sender, args) =>
                {
                    _cachedPathList.Clear();
                    RefreshCachedPathMenu();
                };
                SavedPath.Items.Add(clearMenuItem);
            }
            SaveCachedPath();
        }
        private void SaveCachedPath()
        {
            var list = new List<string>(_cachedPathList);
            File.WriteAllText(CONFIG_PATH, string.Join("\n", list), s_encoding);
        }
        public static string GetRelativePath(string path)
        {
            var relativeTo = Directory.GetCurrentDirectory();
            path = Path.GetFullPath(path);
            if (path == relativeTo) return "./";
            var oldPath = path;
            // 确保两个路径都是以目录分隔符结束
            if (!relativeTo.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            {
                relativeTo += Path.DirectorySeparatorChar;
            }
            if (!File.Exists(oldPath) && !path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            {
                path += Path.DirectorySeparatorChar;
            }
            // 将两个路径转换为Uri对象
            Uri relativeToUri = new Uri(relativeTo);
            Uri pathUri = new Uri(path);
            // 计算两个Uri之间的相对Uri
            Uri relativeUri = relativeToUri.MakeRelativeUri(pathUri);
            // 将相对Uri转换回相对路径字符串
            string relativePath = Uri.UnescapeDataString(relativeUri.ToString());
            return relativePath;
        }
        private void AddCachedPath(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(_srcPath) && string.IsNullOrEmpty(_destPath)) return;
            
            var pathPair = $"{PrefixInput.Text}|{_srcPath}|{_destPath}";
            if (!_cachedPathList.Contains(pathPair))
            {
                _cachedPathList.Insert(0, pathPair);
                RefreshCachedPathMenu();
            }
            ShowTip("已保存地址");
        }
        //保存快捷键
        private void MainWindow_OnKeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) != 0 && e.Key == Key.S)
            {
                AddCachedPath(default, default);
            }
        }
        //应用路径
        private bool ApplyPath(int index)
        {
            if (index >= _cachedPathList.Count) return false;
            var pathPair = _cachedPathList[index].Split('|');
            if (pathPair.Length == SAVE_CONTENT_COUNT)
            {
                //前缀
                PrefixInput.Text = pathPair[0];
                //源
                var srcPath = pathPair[1];
                _srcPath = Directory.Exists(srcPath) ? srcPath : null;
                //目标
                var destPath = pathPair[2];
                _destPath = Directory.Exists(destPath) ? destPath : null;
                RefreshSrcPath();
                RefreshDestPath();
                return true;
            }
            return false;
        }
        
        /// <summary>
        /// 显示提示
        /// </summary>
        public static void ShowTip(string msg)
        {
            MessageBox.Show(msg, "Tip", MessageBoxButton.OK);
        }

        private string _srcPath;
        private void OnSrcDrop(object sender, DragEventArgs e)
        {
            var files = (string[]) e.Data.GetData(DataFormats.FileDrop);
            for (var i = 0; i < files.Length; i++)
            {
                var path = files[i];
                if (Directory.Exists(path))
                {
                    _srcPath = GetRelativePath(path);
                    RefreshSrcPath();
                    return;
                }
            }
            ShowTip("无效文件夹!");
        }

        private string _destPath;
        private void OnDestDrop(object sender, DragEventArgs e)
        {
            var files = (string[]) e.Data.GetData(DataFormats.FileDrop);
            for (var i = 0; i < files.Length; i++)
            {
                var path = files[i];
                if (Directory.Exists(path))
                {
                    _destPath = GetRelativePath(path);
                    RefreshDestPath();
                    return;
                }
            }
            ShowTip("无效文件夹!");
        }

        private void OnConvertClick(object sender, RoutedEventArgs e)
        {
            var result = Convert(Path.GetFullPath(_srcPath), Path.GetFullPath(_destPath));
            if (result.success)
            {
                ShowTip("转换成功!");
            }
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            SaveCachedPath();
        }

        private (bool success, string[] files) Convert(string srcPath, string destPath)
        {
            if (string.IsNullOrEmpty(srcPath) && string.IsNullOrEmpty(destPath))
            {
                ShowTip("未选择文件夹!");
                return (false, null);
            }
            var files = Directory.GetFiles(srcPath, "*.json", SearchOption.TopDirectoryOnly);
            if (files.Length == 0)
            {
                ShowTip("文件夹里未发现任何有效文件!");
                return (false, files);
            }
            for (var i = 0; i < files.Length; i++)
            {
                var path = files[i];
                ItemConverter.Convert(path, destPath, PrefixInput.Text);
            }
            return (true, files);
        }
        
        private void RefreshSrcPath()
        {
            if (!string.IsNullOrEmpty(_srcPath))
            {
                SrcArea.Text = $"源文件夹: \n{_srcPath}";
                SrcArea.FontSize = 22;
            }
            else
            {
                SrcArea.Text = "源文件夹";
                SrcArea.FontSize = 40;
            }
        }
        private void RefreshDestPath()
        {
            if (!string.IsNullOrEmpty(_destPath))
            {
                DestArea.Text = $"目标文件夹: \n{_destPath}";
                DestArea.FontSize = 22;
            }
            else
            {
                DestArea.Text = "目标文件夹";
                DestArea.FontSize = 40;
            }
        }

        private void OnMouseRightButtonUp_Src(object sender, MouseButtonEventArgs e)
        {
            if (!string.IsNullOrEmpty(_srcPath) && Directory.Exists(_srcPath))
            {
                Process.Start(Path.GetFullPath(_srcPath));
            }
        }
        private void OnMouseRightButtonUp_Dest(object sender, MouseButtonEventArgs e)
        {
            if (!string.IsNullOrEmpty(_destPath) && Directory.Exists(_destPath))
            {
                Process.Start(Path.GetFullPath(_destPath));
            }
        }
    }
}